public class EmptyClass {}
public interface HttpResponseContent : EmptyClass {
    public abstract async ByteArray content(HttpResponse response);
}

public interface IStatusCode : EmptyClass {
    public abstract uint16 code();
    public abstract string status();
}
public class StatusCode : EmptyClass, IStatusCode {
    private string _status;
    private uint16 _code;
    public StatusCode(string status, uint16 code) {
        this._status = status;
        this._code = code;
    }
    public string status (){
        return this._status;
    }
    public uint16 code() {
        return this._code;
    }
}
//  public class HttpStatusCode {
//      public static IStatusCode OK = new StatusCode("OK", 200);
//      public static IStatusCode CREATED = new StatusCode("CREATED", 201);
//      public static IStatusCode NOT_FOUND = new StatusCode("NOT FOUND", 404);
//      public static IStatusCode INTERNAL_SERVER_ERROR = new StatusCode("INTERNAL SERVER ERROR", 500);
//  }
public class HttpResponse {
    public Gee.ArrayList<Header.HttpHeader> headers {get; private set; default = new Gee.ArrayList<Header.HttpHeader>(); }
    public IStatusCode status_code {get;set; default = new StatusCode("OK", 200);}
    public Header.ContentType content_type {
        get {
            var temp = this.headers.first_match(header => header is Header.ContentType);
            return temp as Header.ContentType;
        }
    }

    public weak HttpContext context {get; private set;}
    public HttpResponse(HttpContext context) {
        this.context = context;
        this.headers.add(new Header.ContentType(){value = "text/html"});
    }
    public async void write(HttpResponseContent content) throws IOError {
        var bytes = yield content.content(this);
        headers.add(new Header.ContentLength(){
            value = bytes.data.length
        });
        StringBuilder builder = new StringBuilder();
        builder.append(@"HTTP/1.1 $(this.status_code.code()) $(this.status_code.status())\r\n");
        this.headers.foreach((header) => {
            builder.append(@"$(header.build())\r\n");
            return true;
        });
        builder.append("\r\n");
        var outputStream = this.context.connection.output_stream;
        yield outputStream.write_async(builder.data);

        yield outputStream.write_async(bytes.data);
        
        //  yield this.context.close();
    }
}